home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
FishMarket 1.0
/
FishMarket v1.0.iso
/
fishies
/
476-500
/
disk_500
/
wiconify
/
wiconify-source.lzh
/
Source
/
wScreen.c
< prev
next >
Wrap
C/C++ Source or Header
|
1991-04-19
|
14KB
|
474 lines
/*
* WICONIFY A utility that allows you to iconify any Intuition window
* on any screen, and to open WB windows on any screen.
*
* wScreen.c Handles menu and screen functions.
*
* Copyright 1990 by Davide P. Cervone, all rights reserved.
* You may use this code, provided this copyright notice is kept intact.
*/
#define INTUITION_PREFERENCES_H /* don't need 'em */
#include <intuition/intuitionbase.h>
#include <libraries/dosextens.h>
#include "wHandler.h"
#include "wMenu.h"
#define SCREENMEM(p) RASSIZE(p.Width,p.Height*p.Depth)
#define RED(i) (((Color[i])>>8)&0x0F)
#define GREEN(i) (((Color[i])>>4)&0x0F)
#define BLUE(i) ( (Color[i]) &0x0F)
/*
* The newScreen structure for wIconify screens
*/
static struct NewScreen IconScreen =
{0,0, 640,200,2, 0,1, HIRES,CUSTOMSCREEN, NULL,"wIconify Screen",NULL,NULL};
static struct Window *PreviousWindow;
static char *LockName = "UnLock";
extern struct wMenuItem OpenWindowMenu[],
NewScreenMenu[],
IconMenu[],
ScreenMenu[];
/*
* Macros for modifying the menus during menu update
*/
#define ENABLESCREEN(n) ScreenMenu[n].Item.Flags |= ITEMENABLED
#define DISABLESCREEN(n) ScreenMenu[n].Item.Flags &= ~ITEMENABLED
#define ENABLEICON(n) IconMenu[n].Item.Flags |= ITEMENABLED
#define DISABLEICON(n) IconMenu[n].Item.Flags &= ~ITEMENABLED
#define CHECKITEM(n) NewScreenMenu[n].Item.Flags |= CHECKED
#define UNCHECKITEM(n) NewScreenMenu[n].Item.Flags &= ~CHECKED
#define ISCHECKED(n) (NewScreenMenu[n].Item.Flags & CHECKED)
#define SETLOCK(n)\
(((struct IntuiText *)(IconMenu[n].Item.ItemFill))->IText = &LockName[2])
#define SETUNLOCK(n)\
(((struct IntuiText *)(IconMenu[n].Item.ItemFill))->IText = LockName)
/*
* SetScreenMenu()
*
* Check the correct HIRES/LORES menu
* Check or uncheck the INTERLACE and HAM menus
*/
void SetScreenMenu(Modes)
UWORD Modes;
{
if (Modes & HIRES)
{
CHECKITEM(NS_HIRES);
UNCHECKITEM(NS_LORES);
} else {
CHECKITEM(NS_LORES);
UNCHECKITEM(NS_HIRES);
}
if (Modes & LACE) CHECKITEM(NS_INTERLACE); else UNCHECKITEM(NS_INTERLACE);
if (Modes & HAM) CHECKITEM(NS_HAM); else UNCHECKITEM(NS_HAM);
}
/*
* SetActiveMenu()
*
* Get the screen from the backdrop window
* If the screen is the RealWB, don't allow it to be iconified
* If the screen is the current WB or it is in the process of closing
* or real WB is the current WB and so is the screen we are using
* don't allow the MAKEWB menu
* Don't allow the CLOSESCREEN item, unless...
* If the screen is a wIconify screen and it has no windows
* And the only icons on the screen are AUTOREMOVE icons
* Then allow CLOSESCREEN
* If the active backdrop window has changed, update the NEWSCREEN menus
* If there are icons on the screen
* Enable CLEANUP, ORGANIZE and OPENALL
* Otherwise disable them
* Disable the CLOSE item, unless...
* If there are selected icons
* Enable OPEN and UNLOCK and disable CLEANUP, unless..
* While ther eare more selected gadgets
* If the gadget is allowed to be close, enable CLOSE
* If the gadget is not locked
* Set the UNLOCK menu to LOCK
* If the icon can be organized, enable CLEANUP
* Go on to the next selected icon
* Otherwise (no selected icons) disable OPEN and LOCK
* If the screen can hold the tallest menu, set the menu strip
*/
static void SetActiveMenu(theWindow)
struct Window *theWindow;
{
WSCREEN *theScreen;
WICONREF *theIcon;
struct wGadget *theGadget;
Forbid();
theScreen = (WSCREEN *)theWindow->UserData;
if (theScreen == RealWB) DISABLESCREEN(SM_ICONIFY);
else ENABLESCREEN(SM_ICONIFY);
if (theScreen == WBScreen || (theScreen->Flags & WI_CLOSING) ||
(WBScreen == NULL && theScreen == RealWB))
DISABLESCREEN(SM_MAKEWB); else ENABLESCREEN(SM_MAKEWB);
DISABLESCREEN(SM_CLOSESCREEN);
if ((theScreen->Flags & WI_WSCREEN) && theScreen->Window == NULL)
{
theIcon = theScreen->IconRef;
while (theIcon && ((theIcon->Icon.Flags & WI_AUTOREMOVE)))
theIcon = theIcon->Next;
if (theIcon == NULL) ENABLESCREEN(SM_CLOSESCREEN);
}
if (ActiveWindow != PreviousWindow)
SetScreenMenu(theScreen->Screen->ViewPort.Modes);
if (theScreen->BackDrop->FirstGadget)
{
ENABLEICON(IM_CLEANUP);
ENABLEICON(IM_ORGANIZE);
ENABLEICON(IM_OPENALL);
} else {
DISABLEICON(IM_CLEANUP);
DISABLEICON(IM_ORGANIZE);
DISABLEICON(IM_OPENALL);
}
DISABLEICON(IM_CLOSE);
if (theScreen->Selected)
{
ENABLEICON(IM_OPEN);
ENABLEICON(IM_LOCK); SETUNLOCK(IM_LOCK);
DISABLEICON(IM_CLEANUP);
theGadget = theScreen->Selected;
while (theGadget)
{
if ((GADGETICON->Icon.Flags & WI_NOCLOSE) == FALSE)
ENABLEICON(IM_CLOSE);
if ((GADGETICON->Icon.Flags & WI_LOCKED) == FALSE)
{
SETLOCK(IM_LOCK);
if ((GADGETICON->Icon.Flags & WI_NOORGANIZE) == FALSE)
ENABLEICON(IM_CLEANUP);
}
theGadget = theGadget->NextSelect;
}
} else {
DISABLEICON(IM_OPEN);
DISABLEICON(IM_LOCK); SETLOCK(IM_LOCK);
}
Permit();
if (theScreen->Screen->Height >= TOTAL_MENUH)
SetMenuStrip(ActiveWindow,wMenu);
}
/*
* SetWindowMenu()
*
* If a backdrop window is active, remove its menu strip
* If the OpenOn type has changed
* Check and uncheck the correct items in the menu
* If SizeToFit has changed
* Check or uncheck it
* If a backdrop window was active, add the menu strip again
*/
void SetWindowMenu(ScreenType,SizeToFit)
int ScreenType,SizeToFit;
{
short i;
if (ActiveWindow) ClearMenuStrip(ActiveWindow);
Forbid();
if (ScreenType != NOCHANGE)
{
for (i=OW_ACTIVESCRN; i<=OW_REALWB; i++)
{
if (i == ScreenType)
OpenWindowMenu[i].Item.Flags |= CHECKED;
else
OpenWindowMenu[i].Item.Flags &= ~CHECKED;
}
}
if (SizeToFit != NOCHANGE)
{
if (SizeToFit)
OpenWindowMenu[OW_AUTORESIZE].Item.Flags |= CHECKED;
else
OpenWindowMenu[OW_AUTORESIZE].Item.Flags &= ~CHECKED;
}
Permit();
if (ActiveWindow) SetActiveMenu(ActiveWindow);
}
/*
* SetActiveWindow()
*
* If the window is not already the active one
* If there is an old active one
* Get the window's screen
* If it has icons that are being dragged, cancel the dragging
* Remove the menu strip
* Report that the icon window is becoming inactive to anyone who cares
* Set the new active window
* If there is a new window
* Clear any error message from the title
* Setup the menu strip and add it
* Record the fact that this was the last window active
* Report the activation to anyone who wants to know
*/
void SetActiveWindow(theWindow)
struct Window *theWindow;
{
WSCREEN *theScreen;
if (theWindow != ActiveWindow)
{
if (ActiveWindow)
{
theScreen = (WSCREEN *)ActiveWindow->UserData;
if (theScreen->Flags & (WI_STARTDRAG| WI_DRAGGING))
CancelDragging(theScreen);
ClearMenuStrip(ActiveWindow);
ReportMulti(WI_REPORTINACTIVE,ActiveWindow,theScreen);
}
ActiveWindow = theWindow;
if (ActiveWindow)
{
if (ActiveWindow->ScreenTitle != wIconifyTitle)
SetWindowTitles(ActiveWindow,-ONE,wIconifyTitle);
SetActiveMenu(ActiveWindow);
PreviousWindow = ActiveWindow;
ReportMulti(WI_REPORTACTIVATE,ActiveWindow,ActiveWindow->UserData);
}
}
}
/*
* UpdateActiveMenu()
*
* If there is an active window
* Remove its menu, then set up and add the menu again
*/
void UpdateActiveMenu()
{
if (ActiveWindow)
{
ClearMenuStrip(ActiveWindow);
SetActiveMenu(ActiveWindow);
}
}
/*
* SetScreenColors()
*
* If the new scren depth is too big, clip it
* For each color in the map, if no color was specified
* Get it from the screen's color map (always should be the same)
* Set the screen's color map to the specified colors
*/
static void SetScreenColors(theScreen)
struct Screen *theScreen;
{
short i;
struct ViewPort *theVP = &(theScreen->ViewPort);
short Depth = (1 << theScreen->BitMap.Depth);
if (Depth > 32) Depth = 32;
for (i=0; i<Depth; i++)
if (Colors[i] == NOCOLOR) Colors[i] = GetRGB4(theVP->ColorMap,i);
LoadRGB4(theVP,&Colors[0],Depth);
}
/*
* DoNewScreen()
*
* Set the modes and width from the current screen according to whether
* the new screen should be HIRES or not
* Set the modes and height from the current screen according to whether
* the new screen should be interlaced or not
* Set the modes and depth for HAM screens
* If there is enough CHIP memory for the screen plus some extra,
* Attempt to open the screen
* If successful
* Set the new screen's color map
* If the screen got a wIconify backdrop window (usually should)
* Set the screen as a wIconify screen and as the new WB screen
* Otherwise give an error
*/
WSCREEN *DoNewScreen(Depth,oldScreen)
UWORD Depth;
struct Screen *oldScreen;
{
struct Screen *newScreen;
WSCREEN *theScreen = NULL;
UWORD Modes = oldScreen->ViewPort.Modes;
extern long AvailMem();
if (ISCHECKED(NS_HIRES))
{
IconScreen.ViewModes |= HIRES;
IconScreen.Width = (Modes & HIRES)? oldScreen->Width: oldScreen->Width*2;
if (Depth > 4) Depth = 4;
} else {
IconScreen.ViewModes &= ~HIRES;
IconScreen.Width = (Modes & HIRES)? oldScreen->Width/2: oldScreen->Width;
}
if (ISCHECKED(NS_INTERLACE))
{
IconScreen.ViewModes |= LACE;
IconScreen.Height = (Modes&LACE)? oldScreen->Height: oldScreen->Height*2;
} else {
IconScreen.ViewModes &= ~LACE;
IconScreen.Height = (Modes&LACE)? oldScreen->Height/2: oldScreen->Height;
}
if (ISCHECKED(NS_HAM))
{
IconScreen.ViewModes |= HAM;
Depth = 6;
} else {
IconScreen.ViewModes &= ~HAM;
}
IconScreen.Depth = Depth;
if (AvailMem(MEMF_CHIP) > 125 * SCREENMEM(IconScreen) / 100)
{
newScreen = OpenScreen(&IconScreen);
if (newScreen)
{
SetScreenColors(newScreen);
if (theScreen = FindScreen(newScreen))
{
theScreen->Flags |= WI_WSCREEN;
NewWBScreen(theScreen);
}
} else IconError("Can't open New Screen");
} else IconError("Too low on memory to open New Screen");
return(theScreen);
}
/*
* DoScreenMenu()
*
* Do the right thing for each Screen menu item:
* SCREENTOFRONT:
* Send the screen to the front and activate it's backdrop
* SCREENTOBACK:
* Find the screen following this one
* Send the screen to the back
* If the following screen has a backdrop window, activate it
* WBTOFRONT:
* Get the current WB screen and bring it to the front
* Activate its backdrop, if any
* TOGGLETITLE:
* Toggle the title for the screen
* ICONIFY:
* Set up a bogus message and call the Iconify routine to iconify it
* MAKEWB:
* Set the screen as the new WB screen
* Activate the CurrentWB menu item
* NEWCLI:
* Create the NewCLI
* NEWSCREEN:
* Get the subcode
* If it is a depth code
* Create a new screen of the proper depth
* If the screen was created and it has a backdrop window, activate it
* CLOSESCREEN:
* If the screen is a wIconify screen and it has no windows open on it
* Report the screen close to those interested in it
* (some icons may choose to close themselves)
* Remove the auto-remove icons
* If there are no icons left close the screen
*/
int DoScreenMenu(theCode,theScreen,EndItAll)
USHORT theCode;
WSCREEN *theScreen;
int EndItAll;
{
struct Screen *nextScreen;
struct wIconMessage tmpMessage;
switch(ITEMNUM(theCode))
{
case SM_TOFRONT:
ScreenToFront(theScreen->Screen);
ActivateWindow(theScreen->BackDrop);
break;
case SM_TOBACK:
Forbid(); nextScreen = IntuitionBase->FirstScreen; Permit();
if (nextScreen == theScreen->Screen)
nextScreen = nextScreen->NextScreen;
ScreenToBack(theScreen->Screen);
theScreen = FindScreen(nextScreen);
if (theScreen && theScreen->BackDrop)
ActivateWindow(theScreen->BackDrop);
break;
case SM_WBTOFRONT:
if (WBScreen) theScreen = WBScreen; else theScreen = RealWB;
ScreenToFront(theScreen->Screen);
if (theScreen->BackDrop) ActivateWindow(theScreen->BackDrop);
break;
case SM_TOGGLE:
if (theScreen->Screen->Flags & SHOWTITLE)
ShowTitle(theScreen->Screen,FALSE);
else
ShowTitle(theScreen->Screen,TRUE);
break;
case SM_ICONIFY:
tmpMessage.Action = WI_ICONIFY;
tmpMessage.Window = theScreen->BackDrop;
tmpMessage.Flags = 0;
DoIconify(&tmpMessage);
break;
case SM_MAKEWB:
NewWBScreen(theScreen);
SetWindowMenu(OW_CURRENTWB,NOCHANGE);
break;
case SM_NEWCLI:
DoNewCLI(theScreen);
break;
case SM_NEWSCREEN:
theCode = SUBNUM(theCode);
if (theCode >= NS_DEPTH1 && theCode <= NS_DEPTH5)
{
theScreen = DoNewScreen(theCode-NS_DEPTH1+1,theScreen->Screen);
if (theScreen && theScreen->BackDrop)
ActivateWindow(theScreen->BackDrop);
}
break;
case SM_CLOSESCREEN:
if ((theScreen->Flags & WI_WSCREEN) && theScreen->Window == NULL)
{
ReportMulti(WI_REPORTSCREENCLOSE,theScreen->Screen,theScreen);
RemoveAutoIcons(theScreen);
if (theScreen->IconRef == NULL) CloseScreen(theScreen->Screen);
}
break;
}
Permit();
return(EndItAll);
}